//
//  GroupDAO.m
//  iMadeCoreData
//
//  Created by Edward Knutson on 10/13/09.
//  Copyright 2009 Six Four Systems. All rights reserved.
//

#import "GroupDAO.h"

#import <CoreLocation/CoreLocation.h>

#import "Group.h"
#import "Location.h"
#import "Tag.h"
#import "TransferGroup.h"

@implementation GroupDAO

@synthesize context;

- (id)initWithContext:(NSManagedObjectContext *)ctx {
	if(self = [super init]) {
		self.context = ctx;
	}
	return self;
}

- (BOOL)saveGroup:(TransferGroup *)group error:(NSError **)error {
	Group *value = [self groupForTransferGroup:group error:error];
	if(value != nil)
		NSLog(@"save group initial value=%@", value);
	if(*error != nil) {
		NSLog(@"error creating or retrieving group: %@", *error);
		return NO;
	}
	if(value == nil)
		value = (Group *)[NSEntityDescription insertNewObjectForEntityForName:@"Group" inManagedObjectContext:context];
	value.name = group.name;
	value.icsUrl = group.icsUrl;
	value.rssUrl = group.rssUrl;
	value.servicesUrl = group.servicesUrl;
	value.logoUrl = group.logoUrl;
	value.groupDescription = group.groupDescription;
	value.lastUpdated = group.lastUpdated;
	value.inactive = [NSNumber numberWithBool:group.inactive];
	value.subscribed = [NSNumber numberWithBool:group.subscribed];
	if(group.location != nil) {
		NSLog(@"group.location=%@", group.location);
		CLLocationCoordinate2D coord = group.location.coordinate;
		Location *loc = value.location;
		if(loc == nil)
			loc = [NSEntityDescription insertNewObjectForEntityForName:@"Location" inManagedObjectContext:context];
		loc.latitude = [NSNumber numberWithDouble:coord.latitude];
		loc.longitude = [NSNumber numberWithDouble:coord.longitude];
		value.location = loc;
		NSLog(@"value.location=%@", loc);
	} else value.location = nil;
	if(group.tags != nil && [group.tags count] > 0) {
		NSLog(@"group.tags=%@", group.tags);
		NSArray *tags = [self tags:error];
		if(*error != nil) {
			NSLog(@"error getting tags: %@", *error);
			return NO;
		}
		NSMutableDictionary *tagDict = [[NSMutableDictionary alloc] init];
		for(int i=0; i<[tags count]; i++) {
			Tag *tag = (Tag *)[tags objectAtIndex:i];
			[tagDict setValue:tag  forKey:tag.name];
		}
		NSArray *tagNames = [tagDict allKeys];
		NSMutableSet *newTags = [[NSMutableSet alloc] init];
		for(int i=0; i<[group.tags count]; i++) {
			NSString *tagName = [group.tags objectAtIndex:i];
			if([tagNames containsObject:tagName]) {
				[newTags addObject:[tagDict objectForKey:tagName]];
			} else {
				Tag *newTag = (Tag *)[NSEntityDescription insertNewObjectForEntityForName:@"Tag" inManagedObjectContext:context];
				newTag.name = tagName;
				[newTags addObject:newTag];
			}
		}
		[tagDict release];
		value.tags = newTags;
		[newTags release];
	} else value.tags = nil;
	return [context save:error];
}

- (TransferGroup *)groupForName:(NSString *)name error:(NSError **)error {
	TransferGroup *xfer = [[TransferGroup alloc] init];
	xfer.name = name;
	TransferGroup *retVal = [[TransferGroup alloc] initWithGroup:[self groupForTransferGroup:xfer error:error]];
	[xfer release];
	return retVal;
}

- (TransferGroup *)groupForIcsUrl:(NSString *)icsUrl error:(NSError **)error {
	TransferGroup *xfer = [[TransferGroup alloc] init];
	xfer.icsUrl = icsUrl;
	TransferGroup *retVal = [[TransferGroup alloc] initWithGroup:[self groupForTransferGroup:xfer error:error]];
	[xfer release];
	return retVal;
}

- (Group *)groupForTransferGroup:(TransferGroup *)transferGroup error:(NSError **)error {
	NSFetchRequest *request = [[NSFetchRequest alloc] init];
	NSEntityDescription *entity = [NSEntityDescription entityForName:@"Group" inManagedObjectContext:context];
	[request setEntity:entity];	
	NSPredicate *where;
	if(transferGroup.icsUrl != nil)
		where = [NSPredicate predicateWithFormat:@"icsUrl = %@", transferGroup.icsUrl];
	else if(transferGroup.name != nil)
		where = [NSPredicate predicateWithFormat:@"name = %@", transferGroup.name];
	else return nil;
	[request setPredicate:where];
	NSArray *results = [context executeFetchRequest:request error:error];
	[request release];
	if(results != nil && [results count] > 0)
		return [results objectAtIndex:0];
	else return nil;
}

- (NSArray *)groups:(NSError **)error {
	return [self objectsWithType:@"Group" error:error];
}

- (NSArray *)subscribedGroups:(NSError **)error {
	NSPredicate *where = [NSPredicate predicateWithFormat:@"subscribed = YES"];
	return [self objectsWithType:@"Group" predicate:where error:error];
}

- (NSArray *)tags:(NSError **)error {
	return [self objectsWithType:@"Tag" error:error];
}

- (NSArray *)objectsWithType:(NSString *)type error:(NSError **)error {
	return [self objectsWithType:type predicate:nil error:error];
}

- (NSArray *)objectsWithType:(NSString *)type predicate:(NSPredicate *)where error:(NSError **)error {
	NSFetchRequest *request = [[NSFetchRequest alloc] init];
	NSEntityDescription *entity = [NSEntityDescription entityForName:type inManagedObjectContext:context];
	[request setEntity:entity];
	if(where != nil) {
		[request setPredicate:where];
	}
	NSSortDescriptor *order = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
	[request setSortDescriptors:[[NSArray alloc] initWithObjects:order, nil]];
	[order release];
	NSArray *results = [context executeFetchRequest:request error:error];
	
	[request release];
	return results;
}

- (void)dealloc {
	[context release];
	[super dealloc];
}

@end
